<template>
  <div class="standardProgramme-detail">
    <n-card v-if="loading" :bordered="false" class="proCard">
      <n-spin :show="loading" class="loading" />
    </n-card>

    <DFPageDetail v-else :pageOptions="pageOptions" />
  </div>
</template>

<script lang="ts" setup name="StandardProgrammeDetail">
  import lang from '../lang';

  import { useMixins } from '@/hooks/useMixins';

  import {
    addMachineParameter,
    updateMachineParameter,
    infoMachineParameter,
  } from '@/api/gather/machine';

  import {
    connectTypeList,
    connectionTypeList,
    baudRateList,
    dataBitsList,
    protocolList,
    autoOpenList,
    stopBitsList,
    parityList,
    modbusDataTypeList,
    byteOrderList,
    opcuaTypeList,
    computedTypeList,
    isOpenMultiLineList,
  } from './data';

  import { listMachine } from '@/api/base/machine';
  import { listGatherParameter } from '@render/api/gather/parameter';

  import { useProjectSettingStore } from '@/store/modules/projectSetting';

  import { generateRandomValue } from '@/utils/index';

  import { v4 as uuidv4 } from 'uuid';

  const projectStore = useProjectSettingStore();

  const { t, loadLangFn, routerType, message } = useMixins();

  const loading = ref(false);

  const machineList = ref([]);

  const gatherParameterList = ref([]);

  loadLangFn(lang);

  const getModelFn = async () => {};

  getModelFn();

  const initFn = async () => {
    try {
      loading.value = true;

      const res = await Promise.all([listMachine(), listGatherParameter()]);

      const [list1, list2] = res;

      machineList.value =
        list1?.data.map((item) => ({ label: item.machineName, value: item.machineCode })) || [];

      gatherParameterList.value =
        list2?.data.map((item) => ({
          label: item.parameterName,
          value: item.id,
          parameterCode: item.parameterCode,
          parameterName: item.parameterName,
          isCreate: false,
        })) || [];
    } catch (e) {
      console.log(e);
    }

    loading.value = false;
  };

  const connectType = ref(null);

  const connectionType = ref(null);

  const pageOptions = {
    list: [
      {
        type: 'form',
        formSchemas: [
          {
            label: 'accessName',
            required: true,
            maxlength: 100,
          },
          {
            label: 'accessCode',
            required: true,
            editDisabled: true,
            maxlength: 100,
          },
          {
            label: 'machineName',
            prop: 'machineCode',
            component: 'NSelect',
            options: machineList,
            required: true,
          },
          {
            label: 'connectType',
            component: 'NSelect',
            options: connectTypeList,
            required: true,
            componentProps: {
              onUpdateValue: (val, _, _updateFormModelFn) => {
                connectType.value = val;

                // const updateData = {
                //   ip: null,
                //   port: null,
                //   path: null,
                //   baudRate: undefined,
                //   dataBits: undefined,
                //   autoOpen: null,
                //   stopBits: undefined,
                //   parity: null,
                //   protocol: null,
                //   host: null,
                //   rack: undefined,
                //   slot: undefined,
                //   userName: null,
                //   password:null
                // };

                // if (val && updateFormModelFn) {
                //   switch (val) {
                //     case 'modbus':
                //       delete updateData.ip;

                //       delete updateData.port;

                //       delete updateData.path;

                //       delete updateData.baudRate;

                //       delete updateData.dataBits;

                //       delete updateData.autoOpen;

                //       delete updateData.stopBits;

                //       delete updateData.parity;

                //       break;
                //     case 'fins':
                //       delete updateData.ip;

                //       delete updateData.port;

                //       delete updateData.protocol;

                //       break;
                //     case 's7':
                //       delete updateData.ip;

                //       delete updateData.port;

                //       delete updateData.rack;

                //       delete updateData.slot;

                //       break;
                //     case 'opcua':
                //       delete updateData.host;

                //       delete updateData.userName;

                //       delete updateData.password;

                //       break;
                //     default:
                //       break;
                //   }
                // }

                // updateFormModelFn && updateFormModelFn(updateData);
              },
            },
          },
          {
            label: 'connectReadTime',
            maxlength: 100,
            component: 'NInputNumber',
            componentProps: {
              maxlength: 50,
              min: 0,
              precision: 0,
              clearable: true,
              showButton: false,
            },
            required: true,
            requiredRulesType: 'number',
            defaultValue: 300,
          },
          {
            label: 'connectOverTime',
            maxlength: 100,
            component: 'NInputNumber',
            componentProps: {
              maxlength: 50,
              min: 0,
              precision: 0,
              clearable: true,
              showButton: false,
            },
            required: true,
            requiredRulesType: 'number',
            defaultValue: 5000,
          },
          {
            label: 'reConnectNum',
            maxlength: 100,
            component: 'NInputNumber',
            componentProps: {
              maxlength: 50,
              min: 0,
              precision: 0,
              clearable: true,
              showButton: false,
            },
            required: true,
            requiredRulesType: 'number',
            defaultValue: 5,
          },
          {
            label: 'connectionType',
            component: 'NSelect',
            options: connectionTypeList,
            hidden: computed(() => connectType.value !== 'modbus'),
            required: true,
            componentProps: {
              onUpdateValue: (val, _, updateFormModelFn) => {
                connectionType.value = val;

                if (val === 'Serial Port' && updateFormModelFn) {
                  updateFormModelFn({
                    path: 'COM1',
                    baudRate: 9600,
                    dataBits: 8,
                    autoOpen: 0,
                    stopBits: 1,
                    parity: 'none',
                  });
                }

                // const updateData = {
                //   ip: null,
                //   port: null,
                //   path: null,
                //   baudRate: undefined,
                //   dataBits: undefined,
                //   autoOpen: null,
                //   stopBits: undefined,
                //   parity: null
                // };

                // if (val) {
                //   switch (val) {
                //     case 'Serial Port':
                //       updateData.path = 'COM1';

                //       updateData.baudRate = 9600;

                //       updateData.dataBits = 8;

                //       updateData.autoOpen = 0;

                //       updateData.stopBits = 1;

                //       updateData.parity = 'none';
                //       break;
                //     default:
                //       delete updateData.ip;

                //       delete updateData.port;
                //       break;
                //   }
                // }

                // updateFormModelFn && updateFormModelFn(updateData);
              },
            },
          },
          {
            label: 'ip',
            maxlength: 100,
            required: true,
            defaultValue: projectStore.ip,
            hidden: computed(
              () =>
                !(
                  (connectType.value === 'modbus' &&
                    connectionType.value &&
                    connectionType.value !== 'Serial Port') ||
                  connectType.value === 'fins' ||
                  connectType.value === 's7'
                )
            ),
          },
          {
            label: 'port',
            maxlength: 100,
            required: true,
            hidden: computed(
              () =>
                !(
                  (connectType.value === 'modbus' &&
                    connectionType.value &&
                    connectionType.value !== 'Serial Port') ||
                  connectType.value === 'fins' ||
                  connectType.value === 's7'
                )
            ),
          },
          {
            label: 'isOpenMultiLine',
            component: 'NSelect',
            options: isOpenMultiLineList,
            required: true,
            requiredRulesType: 'number',
            defaultValue: 1,
            hidden: computed(
              () =>
                !(
                  connectType.value === 'modbus' &&
                  connectionType.value !== null &&
                  connectionType.value !== 'Serial Port'
                )
            ),
          },
          {
            label: 'path',
            maxlength: 100,
            required: true,
            hidden: computed(
              () => !(connectType.value === 'modbus' && connectionType.value === 'Serial Port')
            ),
          },
          {
            label: 'baudRate',
            component: 'NSelect',
            options: baudRateList,
            required: true,
            requiredRulesType: 'number',
            hidden: computed(
              () => !(connectType.value === 'modbus' && connectionType.value === 'Serial Port')
            ),
          },
          {
            label: 'dataBits',
            component: 'NSelect',
            options: dataBitsList,
            required: true,
            requiredRulesType: 'number',
            hidden: computed(
              () => !(connectType.value === 'modbus' && connectionType.value === 'Serial Port')
            ),
          },
          {
            label: 'autoOpen',
            component: 'NSelect',
            options: autoOpenList,
            required: true,
            requiredRulesType: 'number',
            hidden: computed(
              () => !(connectType.value === 'modbus' && connectionType.value === 'Serial Port')
            ),
          },
          {
            label: 'stopBits',
            component: 'NSelect',
            options: stopBitsList,
            required: true,
            requiredRulesType: 'number',
            hidden: computed(
              () => !(connectType.value === 'modbus' && connectionType.value === 'Serial Port')
            ),
          },
          {
            label: 'parity',
            component: 'NSelect',
            options: parityList,
            required: true,
            hidden: computed(
              () => !(connectType.value === 'modbus' && connectionType.value === 'Serial Port')
            ),
          },

          {
            label: 'protocol',
            component: 'NSelect',
            options: protocolList,
            required: true,
            hidden: computed(() => !(connectType.value === 'fins')),
          },
          {
            label: 'host',
            maxlength: 100,
            required: true,
            hidden: computed(() => !(connectType.value === 'opcua')),
          },
          {
            label: 'rack',
            maxlength: 100,
            component: 'NInputNumber',
            required: true,
            requiredRulesType: 'number',
            componentProps: {
              maxlength: 50,
              min: 0,
              precision: 0,
              clearable: true,
              showButton: false,
            },
            hidden: computed(() => !(connectType.value === 's7')),
          },
          {
            label: 'slot',
            maxlength: 100,
            component: 'NInputNumber',
            required: true,
            requiredRulesType: 'number',
            componentProps: {
              maxlength: 50,
              min: 0,
              precision: 0,
              clearable: true,
              showButton: false,
            },
            hidden: computed(() => !(connectType.value === 's7')),
          },

          {
            label: 'userName',
            maxlength: 100,
            hidden: computed(() => !(connectType.value === 'opcua')),
          },
          {
            label: 'password',
            maxlength: 100,
            hidden: computed(() => !(connectType.value === 'opcua')),
          },
          {
            label: 'remark',
            type: 'textarea',
            common: true,
            giProps: { span: 3 },
            componentProps: {
              'show-count': true,
            },
          },
        ],
      },
      {
        title: t('gatherMachine.table.tableName'),
        type: 'table',
        hasSelection: true,
        ref: 'addressList',
        columns: [
          {
            label: 'parameterName',
            prop: 'parameterId',
            required: true,
            requiredRulesType: 'number',
            itemData: {
              component: 'NSelect',
              options: gatherParameterList,
              componentProps: {
                tag: true,
                'on-create': (label: string) => {
                  const createObj = {
                    label: label,
                    value: uuidv4(),
                    parameterCode: generateRandomValue(16),
                    parameterName: label,
                    isCreate: true,
                  };

                  return createObj;
                },
                onUpdateValue(_v: string, option: any, updateFormModelFn: any, row: any) {
                  if (row && option) {
                    const { value = null, parameterCode = null, isCreate, label } = option;

                    const data: any = {
                      parameterId: value,
                      parameterCode,
                      isCreate,
                      parameterName: label,
                    };

                    if (typeof updateFormModelFn === 'function') {
                      updateFormModelFn(data);

                      if (isCreate) {
                        gatherParameterList.value.push(option);
                      }
                    }
                  } else {
                    typeof updateFormModelFn === 'function' &&
                      updateFormModelFn({
                        parameterId: null,
                        parameterCode: null,
                        isCreate: false,
                        parameterName: null,
                      });
                  }
                },
              },
            },
          },
          {
            label: 'parameterCode',
            // render: (row) => {
            //   console.log(gatherParameterList.value.find(item=>item.value===row.parameterId)?.parameterCode)
            //   return h('span',{
            //     innerText:row.parameterId?gatherParameterList.value.find(item=>item.value===row.parameterId)?.parameterCode:'-'
            //   })
            // }
          },
          {
            label: 'slaveId',
            required: true,
            ifShow: computed(() => connectType.value === 'modbus'),
            itemData: {
              component: 'NInputNumber',
              maxlength: 4,
              precision: 0,
              max: 9999,
              min: 1,
            },
          },
          {
            label: 'startOffset',
            required: true,
            ifShow: computed(() => connectType.value === 'modbus'),
            itemData: {
              defaultValue: 0,
              component: 'NInputNumber',
              maxlength: 5,
              precision: 0,
              max: 99999,
              min: 0,
            },
          },
          {
            label: 'address',
            required: true,
            ifShow: computed(() => connectType.value === 'modbus'),
            itemData: {
              component: 'NInputNumber',
              maxlength: 5,
              precision: 0,
              max: 99999,
              min: 0,
            },
          },
          {
            label: 'finsAddress',
            required: true,
            ifShow: computed(() => connectType.value === 'fins'),
            itemData: {
              maxlength: 100,
            },
          },
          {
            label: 'type',
            required: true,
            ifShow: computed(() => connectType.value === 'modbus' || connectType.value === 'fins'),
            itemData: {
              component: 'NSelect',
              options: modbusDataTypeList,
              componentProps: {
                onUpdateValue: (val, _, updateFormModelFn) => {
                  if (updateFormModelFn) {
                    let leng = null;

                    switch (String(val).toLowerCase()) {
                      case 'int':
                      case 'int8':
                      case 'int16':
                      case 'uint16':
                      case 'enum':
                      case 'bool':
                        leng = 2;
                        break;
                      case 'int32':
                      case 'uint32':
                      case 'float':
                      case 'real':
                        leng = 4;
                        break;
                      case 'int64':
                      case 'uint64':
                      case 'double':
                        leng = 8;
                        break;
                      default:
                        break;
                    }

                    updateFormModelFn({ type: val, leng });
                  }
                },
              },
            },
          },
          {
            label: 'leng',
            ifShow: computed(() => connectType.value === 'modbus' || connectType.value === 'fins'),
            itemData: {
              defaultValue: 0,
              component: 'NInputNumber',
              maxlength: 4,
              precision: 0,
              max: 9999,
              min: 0,
            },
          },
          {
            label: 'decimalPlaces',
            required: true,
            ifShow: computed(() => connectType.value === 'modbus' || connectType.value === 'fins'),
            itemData: {
              defaultValue: 0,
              component: 'NInputNumber',
              maxlength: 4,
              precision: 0,
              max: 9999,
              min: 0,
            },
          },
          {
            label: 'byteOrder',
            required: true,
            ifShow: computed(() => connectType.value === 'modbus' || connectType.value === 'fins'),
            itemData: {
              defaultValue: 'none',
              component: 'NSelect',
              options: byteOrderList,
            },
          },
          {
            label: 'bitAccessCodeObj',
            ifShow: computed(() => connectType.value === 'modbus' || connectType.value === 'fins'),
            itemData: {
              component: 'NInput',
            },
          },
          {
            label: 'computedType',
            required: true,
            ifShow: computed(() => connectType.value === 'modbus' || connectType.value === 'fins'),
            itemData: {
              defaultValue: 'none',
              component: 'NSelect',
              options: computedTypeList,
            },
          },
          {
            label: 'computedNum',
            required: true,
            ifShow: computed(() => connectType.value === 'modbus' || connectType.value === 'fins'),
            itemData: {
              defaultValue: 0,
              component: 'NInputNumber',
              maxlength: 5,
              precision: 0,
              max: 99999,
              min: 0,
            },
          },
          {
            label: 's7Address',
            ifShow: computed(() => connectType.value === 's7'),
            itemData: {
              maxlength: 100,
            },
          },
          {
            label: 'opcuaAddress',
            ifShow: computed(() => connectType.value === 'opcua'),
            itemData: {
              maxlength: 100,
            },
          },
          {
            label: 'opcuaType',
            required: true,
            ifShow: computed(() => connectType.value === 'opcua'),
            itemData: {
              component: 'NSelect',
              options: opcuaTypeList,
            },
          },
          {
            label: 'remark',
            common: true,
            itemData: {
              maxlength: 100,
            },
          },
        ],
      },
    ],
    formLabelWidthEn: 100,
    descriptionsListLabelWidthEn: 150,
    routeName: 'gatherMachine',
    addDataFn: addMachineParameter,
    updateDataFn: updateMachineParameter,
    getDataFn: infoMachineParameter,
    handleEditDataFn: (res) => {
      const { data } = res;

      connectionType.value = data.connectionType;

      connectType.value = data.connectType;

      if (data.addressList && data.addressList.length) {
        for (const item of data.addressList) {
          if (item.parameterId) {
            item.parameterCode =
              gatherParameterList.value.find((gItem) => gItem.value === item.parameterId)
                ?.parameterCode || null;
          }
        }
      }

      if (routerType === 'copy') {
        delete data.id;

        delete data.accessCode;

        delete data.accessName;

        delete data.machineCode;

        if (data.addressList && data.addressList.length) {
          for (const item of data.addressList) {
            delete item.id;

            delete item.accessCode;
          }
        }
      }

      return data;
    },
    beforeSubmitFn: (res) => {
      const { addressList = [] } = res;

      if (addressList && addressList.length) {
        const counts = {};

        const isSubmit = addressList.every((item) => {
          const { parameterId } = item;

          if (!counts[parameterId]) {
            counts[parameterId] = parameterId;

            return true;
          }

          return false;
        });

        if (!isSubmit) {
          message.error(t('gatherMachine.tipMsg.sameAccessCode'));
        }

        return isSubmit;
      }

      return true;
    },
  };

  initFn();
</script>

<style lang="less" scoped>
  .standardProgramme-detail {
    position: relative;
    .loading {
      width: 100%;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
    }
  }
</style>
